#ifndef __ONB_H__
#define __ONB_H__

#include "vector3.h"

namespace venus {
	class ONB {
	public:
		ONB() : 
		  _U( 1.f, 0.f, 0.f ),
		  _V( 0.f, 1.f, 0.f ),
		  _W( 0.f, 0.f, 1.f ) { }


	    /************************************************************************
		 * ASSUMPTION: a, b and c are orthonormal basis, and satisfies right-hand rule
		 ************************************************************************/
		ONB( const Vector3& a, const Vector3& b, const Vector3& c )
			: _U( a ), _V( b ), _W( c )	{ }

		void Set( const Vector3& a, const Vector3& b, const Vector3& c )
		{
			_U = a; _V = b; _W = c;
		}

		/************************************************************************
		 * ASSUMPTION: the parameter is not zero
		 ************************************************************************/
		void InitFromU( const Vector3& a_U );
		void InitFromV( const Vector3& a_V );
		void InitFromW( const Vector3& a_W );

		/************************************************************************
		 * The first one is simply normalized,
		 * the second is normalized and it's direction can be adjusted
		 * ASSUMPTION: neither is zero, and they are not parallel to each other
		 ************************************************************************/
		void InitFromUV( const Vector3& a_U, const Vector3& a_V );
		void InitFromVU( const Vector3& a_V, const Vector3& a_U );

		void InitFromUW( const Vector3& a_U, const Vector3& a_W );
		void InitFromWU( const Vector3& a_W, const Vector3& a_U );

		void InitFromVW( const Vector3& a_V, const Vector3& a_W );
		void InitFromWV( const Vector3& a_W, const Vector3& a_V );

		friend istream& operator>>( istream& a_IStream, ONB& a_ONB );
		friend ostream& operator<<( ostream& a_OStream, const ONB& a_ONB );
		//friend bool operator==( const ONB& a_ONB1, const ONB& a_ONB2 );

		const Vector3& U() const { return _U; }
		const Vector3& V() const { return _V; }
		const Vector3& W() const { return _W; }

	private:
		Vector3 _U, _V, _W;
	};
}

#endif//__ONB_H__
